package com.yzh.luckydraw.domain.strategy.service.draw.impl;

import com.alibaba.fastjson.JSON;
import com.yzh.luckydraw.domain.strategy.service.algorithm.IDrawAlgorithm;
import com.yzh.luckydraw.domain.strategy.service.draw.AbstractDrawBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 抽奖过程方法实现
 */
@Service("drawExec")
public class DrawExecImpl extends AbstractDrawBase {
    private Logger logger = LoggerFactory.getLogger(DrawExecImpl.class);
    
    @Override
    protected List<String> queryExcludeAwardIds(Long strategyId) {
        List<String> excludeAwardIds = strategyRepository.queryNoStockStrategyAwardList(strategyId);
        logger.info("执行抽奖策略 strategyId：{}，无库存排除奖品列表ID集合 awardList：{}", strategyId, JSON.toJSONString(excludeAwardIds));
        return excludeAwardIds;
    }

    @Override
    protected String drawAlgorithm(Long strategyId, IDrawAlgorithm drawAlgorithm, List<String> excludeAwardIds) {
        //执行抽奖
        String awardId = drawAlgorithm.randomDraw(strategyId, excludeAwardIds);
        //校验结果
        if (awardId == null) {
            return null;
        }
        /*
         * 扣减库存，暂时使用行级锁方式扣减库存，后续会优化为redis分布式锁
         * 在分库分表下的正常数据量下的个人数据记录中，是可以使用行级锁的，因为只影响自己的记录，不影响其他人的
         */
        boolean isSuccess = strategyRepository.deductStock(strategyId, awardId);
        //返回结果，实际场景中，如果中奖奖品为空会给用户发兜底奖品（优惠卷）
        return isSuccess ? awardId : null;
    }
}
